1. Field of the Invention
This invention relates to computer software, and more particularly to a system and method for providing class dependency graph-based class loading and reloading in applications.
2. Description of the Related Art
Today's long-running programs have given rise to a complex set of demands. One such demand is the need for the hot deployment and redeployment of programmatic logic. This need is particularly prevalent in application server environments, where a server process may continue running uninterrupted for months or more. It is often necessary to make changes in the presentation logic and/or the business logic of applications. In the world of application servers that run large and often mission-critical applications, taking the server offline to get these changes reflected may not be possible. In the development environment, it is quite common for a developer to deploy an application or Enterprise JavaBeans™ (EJB™) bean, test it, and make certain changes to get desired results. Since deploying a business component like an EJB™ or assembling an application in itself is quite complex, in the development environment, whenever the developer changes a bean, the server has to be restarted to check the changes.
In application servers based on the J2EE™ (Java™ 2 Platform, Enterprise Edition) distributed computing model, the business presentation is typically represented using servlets and/or JavaServer Pages™ (JSP™), and the business logic typically runs in the form of distributed components such as EJBs. These application servers may, to an extent, provide for the reloading of servlets and JSPs at runtime through a custom class loader mechanism. The Java™ programming language provides class loaders for such needs. Implementations may use the Java™ class loading framework for loading and reloading of classes.
A Java™ class loader is a namespace that may include business (or other application) logic, in the form of class bytes, associated with the names. The design of the Java™ Virtual Machine (JVM) imposes a restriction that a class loader cannot be asked to change its elements. New elements (e.g. the class bytes for the class names) may, however, be added to the namespace. However, a class loader may be replaced. For example, if a class associated with a class loader is changed, the old class loader, configured to load the original class, is replaced with a new class loader configured to load the changed class.
Classes may have dependencies between each other. If a class c1 accesses some functionality in a class c2, then c2 should be accessible in the same namespace as c1, or alternatively in a namespace accessible by the class loader. The class loaders associated with these other namespaces are conventionally referred to as “parent class loaders.” These class loaders may be arranged in some topology. For example, a parent-child tree topology may be used, for example based on the Java™ Development Kit (JDK™), version 1.2 class loading delegation model.
A possible architecture for a class reloading mechanism is to have a separate class loader for each application, and to have the system class loader as the parent of the class loaders. The system class loader loads the standard classes and the application server's core classes, and the application class loader loads the user-defined classes. This architecture is illustrated in FIG. 1. Since there is a single class loader that handles all the classes in an application, all the loaded classes will be reloaded for a single class change. This is added overhead for the application server.
Class Loaders
The following section provides background information on class loaders, class loading, and class reloading. This information refers to the Java™ programming language and to the Java™ Virtual Machine (JVM) architecture as an example of an implementation of class loaders, loading, and reloading. This information, however, may be relevant to other architectures, programming languages, environments including virtual machine environments, platforms, applications, application servers and/or implementations of class loaders.
The default class loading mechanism in the JVM is to load the class file from a specified location into the memory and to execute the byte code as and when the request comes in for a particular class. The default class loader, which may be referred to as a system class loader, caches the class once it loads the class. Therefore, if the class file changes after loading the class, the changes are not reflected in the program unless JVM is restarted.
Class loaders are one of the cornerstones of virtual machine architectures such as the JVM architecture. Class loaders may enable a virtual machine to load classes without knowing anything about the underlying file system semantics, and may allow applications to dynamically load classes such as Java™ classes as extension modules. For example, JVM has an embedded class loader called the primordial/system class loader. Virtual machines such as JVM may also provide a facility by which a user can introduce a custom class loader. For example, in JVM, a hook is provided to the loading mechanism through the custom class loaders. A custom class loader may load a class before or after the primordial class loader attempts to load the class. Therefore, certain policies pertaining to loading classes, maintenance, fetching classes, etc. may be implemented by the custom class loader. The custom class loader may also, for example, specify the remote location from which the classes are loaded, and/or assign appropriate security. Programmatically speaking, class loaders are ordinary objects that may be defined in code (e.g. Java™ code). In Java™, class loaders are instances of subclasses of abstract class Classloader.
In Java™, classes and interfaces are dynamically loaded, linked, and initialized. Loading is the process of finding the binary form of a class or interface type with a particular name and constructing, from that binary form, a Class object to represent the class or interface. For example, a class or Interface C's loading is triggered by another class or interface D, which references C through its runtime constant pool. Class or interface loading may also be triggered by D invoking methods in certain Java™ class libraries such as Reflection. Once a class is loaded, it is linked and resolved. Linking involves verifying and preparing a class, its direct superinterfaces, its direct superclass and its element type (if its an array type). Resolving is the process of dynamically determining concrete values from symbolic references in the runtime constant pool is known as resolving.
A class object loaded by loader L1 has a runtime signature <C1,L1> inside JVM. The same class C1, when loaded by L2, has the runtime signature <C1,L2> and thus can be distinguished from <C1,L1> by its runtime signature.
Once a class loader loads a class, the same class loader cannot load a different version of the class, as JVM internally tightly couples the class with the class loader. To maintain type safety, the virtual machine must be able to consistently obtain the same class type for a given class name and loader. The virtual machine cannot trust any user-defined loadClass method to consistently return the same type for a given name. JVM has to ensure security and behavioral consistency. Therefore, the virtual machine internally maintains a loaded class cache. The loaded class cache maps class names and the initiating loaders.
The next time the loader tries to load the class, an already cached copy of the class will be returned, but reloading will not be performed. So to reload a class requires the class to be loaded by a new loader. A runtime class type is determined not by its name alone but by its class name and its defining class loader. Therefore, two instances of the runtime class C1 loaded by different loaders L1 and L2 are different and, as mentioned above, distinguishable by their signatures.
Delegation Mechanism
The Java™ Development Kit (JDK™), version 1.2, introduces a delegation model to maintain consistency of loaded classes. Using JDK™ 1.2, class loaders may be linked in a parent-child relationship. In a class loader, a defineClass method may be provided to define the class for the JVM. A loadClass method may be called as a result of the class resolution operation, or alternatively by explicit request of the application. A class is associated with the loader that defines it. In the delegation model, the parent class loader, if one exists, may be given the opportunity to load the class before the class loader attempts to load the class itself. This parent class loader may in turn have a parent class loader, which may be given the opportunity to load the class before the class or its immediate parent class loader attempts to load the class. This delegation may continue, for example, until a class loader is reached with no parent class loader.
J2EE™
The Java™ 2 Platform, Enterprise Edition (J2EE™) defines the standard for developing multi-tier enterprise Applications. J2EE™ simplifies enterprise applications by basing them on standardized, modular components, by providing a complete set of services to those components, and by handling many details of application behavior automatically, without complex programming. J2EE™ takes advantage of many features of the Java™ 2 Platform, Standard Edition, such as “Write Once, Run Anywhere™” portability, JDBC™ (Java™ DataBase Connectivity) API for database access, Object Management Group's Common Object Request Broker Architecture (CORBA) technology for interaction with existing enterprise resources, and a security model that protects data even in internet applications. Building on this base, J2EE™ adds full support for EJB™ components, Java™ Servlets API, and JSP™ among many other technologies.
Application Servers
An application server is a server program in a computer in a distributed network that provides a framework to host business logic for an application program. The application server is frequently viewed as part of a three-tier application, consisting of a graphical user interface (GUI) server, an application (business logic) server, and a database server. More descriptively, it can be viewed as dividing an application into:                A first-tier, front-end, Web browser-based graphical user interface, usually at a personal computer or workstation.        A middle-tier business logic application or set of applications, possibly on a local area network or intranet server.        A third-tier, back-end, database and transaction server, sometimes on a mainframe or large server.        
Older, legacy application databases and transaction management applications are part of the back end or third tier. The application server is the middleman between browser-based front-ends and back-end databases and legacy systems.
iPlanet™ Application Server (iAS™)
The iPlanet™ Application Server (iAS™), offered by iPlanet™ E-Commerce Solutions, provides a robust J2EE™ e-commerce platform for the development, deployment, and management of application services to a broad range of servers, clients, and devices. iAS™ maximizes application re-use and developer collaboration and demonstrates the potential of leveraging Java™ for large-scale web and wireless applications.